import { app, screen, shell, BrowserWindow, ipcMain, Tray, Menu, dialog } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import initErrorHandler from './utils/errorHandler'
import service from './utils/service'
import MsgHandler from './utils/ipcMsgHandler'
import HandleCameraMsg from './utils/cameraMsgHandler'
import { exportExcel } from './utils/export-excel'

// 主窗口
/**
 * @type {BrowserWindow}
 */
let mainWindow = null
// 只允许程序存在一个运行实例
const gotTheLock = app.requestSingleInstanceLock() // 单实例锁
if (!gotTheLock) {
  app.quit()
} else {
  app.on('second-instance', () => {
    if (mainWindow) {
      mainWindow.show()
    }
  })
}
/**
 * @type {MsgHandler}
 */
let msgIns = null
let isCloseApp = false
const closeApp = () => {
  isCloseApp = true
  app.quit()
}
// 创建主窗口
function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 1000,
    height: 600,
    minWidth: 800,
    minHeight: 600,
    show: false,
    title: '车辆识别系统',
    autoHideMenuBar: true,
    icon: join(__dirname, '../../resources/svg-icon.ico'),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    // 加载vite启动的前端服务地址
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}
/**提示窗口
 * @type {BrowserWindow}
 */
let warningWindow = null
// 创建提示窗口
function createWarningWindow(warningData, timeInterval) {
  warningWindow = new BrowserWindow({
    width: 300,
    height: 200,
    minWidth: 300,
    minHeight: 200,
    maxWidth: 300,
    maxHeight: 200,
    show: false,
    minimizable: false,
    maximizable: false,
    alwaysOnTop: false,
    focusable: false,
    title: '车牌确认提示',
    autoHideMenuBar: true,
    icon: join(__dirname, '../../resources/svg-icon.ico'),
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  })
  // 弹出时，将提示窗口置于右下角
  const setWindow = () => {
    const primaryDisplay = screen.getPrimaryDisplay()
    // 获取工作区，即除去任务栏的区域的宽高
    const { width, height } = primaryDisplay.workAreaSize
    // 获取警告弹窗的宽高
    const windowSize = warningWindow.getBounds()
    // 计算出窗口右下角的坐标
    let x = width - windowSize.width
    let y = height - windowSize.height
    warningWindow.setPosition(x, y, false)
  }
  // 窗口打开时，向渲染进程发送提示消息
  warningWindow.on('ready-to-show', () => {
    setWindow()
    warningWindow.show()
    warningWindow.webContents.send('warning-data', warningData, timeInterval)
  })
  // 关闭时只销毁窗口
  warningWindow.on('close', (event) => {
    event.preventDefault()
    warningWindow.destroy()
    warningWindow = null
  })
  ipcMain.on('close-warning', () => {
    warningWindow.destroy()
    warningWindow = null
  })
  warningWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  warningWindow.loadFile(join(__dirname, '../renderer/warning-win/index.html'))
}
app.whenReady().then(() => {
  // 设置应用程序在用户登录时自动启动
  app.setLoginItemSettings({
    openAtLogin: false,
    path: app.getPath('exe') // 可执行文件的路径
  })
  electronApp.setAppUserModelId('com.electron')
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // 创建窗口
  createWindow()
  mainWindow.on('close', (event) => {
    // 非app.quit关闭app，都只是最小化到系统托盘
    if (!isCloseApp) {
      // 阻止默认行为，即关闭窗口
      event.preventDefault()
      mainWindow.hide()
    }
  })
  // 开启全局错误拦截
  initErrorHandler.initGlobalErrorHandler()
  // 启动服务
  service.start()
  // 设置服务回调
  service.setMsgCallback((result) => {
    let data = HandleCameraMsg.filterMsg(result)
    if (data) {
      // 接收到服务回调数据，传输到渲染进程
      msgIns.sendMsgToIpcrenderer({ type: 'camera', data })
    }
  })

  // 注册主渲进程通信实例
  msgIns = new MsgHandler(mainWindow)
  // 设置回复ip消息
  msgIns.watchMsgFromIpcRenderer('getIp', (evt) => {
    msgIns.sendMsgToIpcrenderer({
      type: 'local-ip',
      data: service.getLocalIp() + ':' + service.port
    })
  })
  msgIns.watchMsgFromIpcRenderer('restartServer', (evt, data) => {
    service.stop().then(() => {
      service.start(data).then(() => {
        msgIns.sendMsgToIpcrenderer({ type: 'serverHasRestart', data: data })
      })
    })
  })
  // 调起文件管理器，导出当前数据
  msgIns.watchMsgFromIpcRenderer('exportExcel', (evt, data) => {
    dialog
      .showOpenDialog({
        properties: ['openDirectory']
      })
      .then((r) => {
        if (!r.canceled) {
          exportExcel(data.sheets, r.filePaths[0], data.filename).then((r) => {
            console.log(123, r)
            msgIns.sendMsgToIpcrenderer({ type: 'export-result', data: r })
          })
        }
      })
  })
  // 监听是否调起警告弹窗
  msgIns.watchMsgFromIpcRenderer('warning', (evt, data, timeInterval) => {
    console.log(22, timeInterval)
    if (warningWindow && !warningWindow.isDestroyed()) {
      warningWindow.show()
      warningWindow.webContents.send('warning-data', data, timeInterval)
      return
    }
    createWarningWindow(data, timeInterval)
  })

  // 设置系统托盘
  setTray()
  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    } else {
    }
  })
})
// 设置托盘
let tray = null
function setTray() {
  tray = new Tray(join(__dirname, '../renderer/svg-icon.ico'))
  // 设置托盘菜单
  let contextMenu = Menu.buildFromTemplate([
    {
      label: '打开',
      click: function () {
        // 当点击此菜单项时，执行的代码
        mainWindow.show()
      }
    },
    {
      label: '退出',
      click: function () {
        closeApp()
      }
    }
  ])

  tray.setToolTip('车道识别软件')
  tray.setContextMenu(contextMenu)
  // 双击托盘打开应用
  tray.on('double-click', () => {
    mainWindow.show()
  })
}
app.on('window-all-closed', (event) => {
  if (process.platform !== 'darwin') {
    closeApp()
  }
})
